package cn.fcq.ymcc.service.impl;

import cn.fcq.ymcc.constants.CourseConstant;
import cn.fcq.ymcc.constants.YmccError;
import cn.fcq.ymcc.domain.CourseType;
import cn.fcq.ymcc.dto.CrumsCourseTypeDto;
import cn.fcq.ymcc.mapper.CourseTypeMapper;
import cn.fcq.ymcc.service.ICourseTypeService;
import cn.fcq.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author lao.xu
 * @since 2022-07-20
 */
@Service
@Slf4j
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private CourseConstant courseConstant;

    /**
     * 查询无限级课程树
     * @return
     */
    @Override
    @Cacheable(cacheNames="coursetype",key="'tree'")
    public List<CourseType> treeData() {
        //没有就查询数据库
        return tree();
    }

    /**
     * 获取面包屑
     * @param courseTypeId
     * @return
     */
    @Override
    public List<CrumsCourseTypeDto> crumbs(Long courseTypeId) {
        List<CrumsCourseTypeDto> list = new ArrayList<>();
        return Arrays.asList(  selectById(courseTypeId).getPath().split("\\.")).stream().map(s->{
            CrumsCourseTypeDto dto = new CrumsCourseTypeDto();
            CourseType ownerType = selectById(Long.valueOf(s));
            AssertUtil.isNotNull(ownerType, YmccError.COURSE_TYPEDELETE_CODE.getMessage());
            Wrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid", ownerType.getPid());
            List<CourseType> otherTypes = selectList(wrapper);
            dto.setOwnerType(ownerType);
            dto.setOtherTypes(otherTypes);
            return dto;}).collect(Collectors.toList());
    }

    /**
     *  redis先查
     * @return
     * 封装无限极树
     */
    public List<CourseType> treeData2() {
        // 查询redis中是否有无限性级树
        String courseTypeTree = courseConstant.getCourseTypeTree();
        Object o = redisTemplate.opsForValue().get(courseTypeTree);
        if (o !=null){
            log.info("走redis查询");
            // 有就直接返回
            return (List<CourseType>) o;
        }
        log.info("走mybatis查询");
        List<CourseType> tree = tree();
        redisTemplate.opsForValue().set(courseTypeTree,tree);
        //没有就查询数据库
        return tree;
    }

    /**
     * * 1.查询数所有数据，放到内存
     *      *      *      * 2.查找出顶级组成firstList ---- 返回的List
     *      *      *      * 3.所有不是顶级的都找自己的上级，并把自己加入到上级的children
     * 封装无限极树
     * @return
     */
    public List<CourseType> tree() {
        //查询所有数据
        List<CourseType> courseTypes = selectList(null);
        Map<Long, CourseType> map = courseTypes.stream().collect(Collectors.toMap(CourseType::getId, ct -> ct));
        //2.查出顶级
        List<CourseType> firstList = new ArrayList<>();
        for (CourseType type:courseTypes){
            if (type.getPid()==null || type.getPid().intValue()==0){
                firstList.add(type);
            }else {
                //子层
                map.get(type.getPid()).getChildren().add(type);
            }
        }
        return firstList;
    }


    @Override
    @CacheEvict(cacheNames="coursetype",key="'tree'")
    public boolean insert(CourseType entity) {

        boolean insert = super.insert(entity);
        /*if (insert){
            //清楚redis缓存
            String courseTypeTree = "coursetypetree";
            redisTemplate.delete(courseTypeTree);
        }*/
        return insert;
    }

    @Override
    @CacheEvict(cacheNames="coursetype",key="'tree'")
    public boolean updateById(CourseType entity) {
        boolean update = super.updateById(entity);
      /*  if (update){
            //清楚redis缓存
            String courseTypeTree = "coursetypetree";
            redisTemplate.delete(courseTypeTree);
        }*/
        return update;
    }

    @Override
    @CacheEvict(cacheNames="coursetype",key="'tree'")
    public boolean deleteById(Serializable id) {
        boolean delete = super.deleteById(id);
       /* if (delete){
            //清楚redis缓存
            String courseTypeTree = "coursetypetree";
            redisTemplate.delete(courseTypeTree);
        }*/
        return delete;
    }
}
